package com.ricky.mq.client.code.constant;

import cn.hutool.core.util.StrUtil;
import com.ricky.mq.client.Version;

/**
 * 报文模板
 *
 * @author ricky
 * @since 2020.06.18
 */
public class MessageTemplate {

    /**
     * 请求头 长度4
     */
    private final String HEAD = "FADA";
    /**
     * 报文长度 长度8
     */
    private int length;
    /**
     * 版本域 长度4
     */
    private final String version = Version.MESSAGE_VERSION;
    /**
     * 命令码 长度4
     */
    private String commandCode;
    /**
     * 数据域 长度不确定
     */
    private String data;
    /**
     * 效验域 长度4
     */
    private int validity;
    /**
     * 结束域 长度4
     */
    private final String TAIL = "ADAF";

    public static MessageTemplate build() {
        return new MessageTemplate();
    }

    public String getHead() {
        return HEAD;
    }

    private String getLength() {
        return StrUtil.padPre(Integer.toHexString(length), 8, "0");
    }

    private void setLength() {
        this.length = this.getHead().length() + 8 + this.getVersion().length()
                + this.getCommandCode().length() + this.getData().length()
                + this.getValidity().length() + this.getTail().length();
    }

    public String getVersion() {
        return version;
    }

    public String getCommandCode() {
        return commandCode;
    }

    public MessageTemplate setCommandCode(String commandCode) {
        this.commandCode = commandCode;
        return this;
    }

    public String getData() {
        return data;
    }

    public MessageTemplate setData(String data) {
        this.data = data;
        return this;
    }

    public String getValidity() {

        return StrUtil.padPre(Integer.toHexString(this.validity), 4, "0");
    }

    public void setValidity() {
        StringBuilder sb = new StringBuilder();
        sb.append(getHead())
                .append(getLength())
                .append(getVersion())
                .append(getCommandCode())
                .append(getData());

        for (int i = 0; i < sb.length(); i += 2) {
            this.validity += Integer.parseInt(sb.substring(i, i + 2), 16);
        }

        this.validity &= 0xff;
    }

    public String getTail() {
        return TAIL;
    }

    /**
     * 组装报文
     *
     * @return 报文
     */
    public String assemblyData() {
        setLength();
        setValidity();

        StringBuilder sb = new StringBuilder();
        sb.append(getHead())
                .append(getLength())
                .append(getVersion())
                .append(getCommandCode())
                .append(getData())
                .append(getValidity())
                .append(getTail());

        return sb.toString();
    }
}
